package core.report;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import core.FileOperator;
import core.testcases.TestCase;
import core.testcases.TestStep;
/**
 * Description   : Functional Test Script
 * @author angel.tsvetkov
 */
public class Reporting 
{
	// HEADER
	private final String PROJECT_NAME = "[PROJECT_NAME]";

	private final String TC_ID = "[TC_ID]";

	private final String TC_DESCRIPTION = "[TC_DESCRIPTION]";

	private final String EXECUTED_BY = "[EXECUTED_BY]";

	private final String CREATED_BY = "[CREATED_BY]";

	private final String DATE_OF_EXECUTION = "[DATE_OF_EXECUTION]";

	private final String REQUIREMENTS = "[REQUIREMENTS]";

	private final String DEFECTS = "[DEFECTS]";

	private final String COMMENTS = "[COMMENTS]";

	// Preconditions
	private final String PRECONDITIONS = "[PRECONDITIONS]";

	// Test Step
	private final String TS_RESULT = "[TS_RESULT]";

	private final String TEST_STEP = "[TEST_STEP]";

	private final String TEST_STEPS = "[TEST_STEPS]";

	private final String STEP_ACTIONS = "[STEP_ACTIONS]";

	private final String TEST_STEP_HTML = "<table style=\"width:100%; background-color:#F0EDEE; \">"
			+ "<tr>"
			+ "<td class=\"style7\">[TS_RESULT]</td>"
			+ "<td style = \"font-size: large; font-weight: bold;\">[TEST_STEP]</td>"
			+ "</tr>" + "[STEP_ACTIONS]" + "</table><p></p>";

	private final String STEP_ACTIONS_HTML = "<tr>"
			+ "<td class=\"style7\">&nbsp;</td>"
			+ "<td><span style = \"font-size: medium;\">[STEP_ACTIONS]</span>&nbsp;</td>"
			+ "</tr>";

	// Test Case
	private final String TC_RESULT = "[TC_RESULT]";

	private final String TC_BRIEF_DESCRIPTION = "[TC_BRIEF_DESCRIPTION]";

	//Format report header section by replacing the markers with appropriate information
	private String formatHeader(String report, String projectName,
			String testCaseID, String testCaseDescription, String executedBy,
			String createdBy, String requrements, String defects,
			String comments) {
		report = report.replace(PROJECT_NAME, projectName);
		report = report.replace(TC_ID, testCaseID);
		report = report.replace(TC_DESCRIPTION, testCaseDescription);
		report = report.replace(EXECUTED_BY, executedBy);
		report = report.replace(CREATED_BY, createdBy);
		report = report.replace(DATE_OF_EXECUTION, now("yyyy/MM/dd HH:mm:ss"));
		report = report.replace(REQUIREMENTS, requrements);
		report = report.replace(DEFECTS, defects);
		report = report.replace(COMMENTS, comments);
		return report;
	}

	//Format report footer section by replacing the markers with appropriate information
	private String formatFooter(String report, String testCaseresult,
			String testCaseBriefdescription) {
		report = report.replace(TC_RESULT, testCaseresult);
		report = report.replace(TC_BRIEF_DESCRIPTION, testCaseBriefdescription);

		return report;
	}

	//Format report precondition section by replacing the markers with appropriate information
	private String formatPreconditions(String report, TestCase testCase) {
		String reportPreconditions = "";
		String preconditions = "";

		for (int iIdx = 0; iIdx < testCase.preconditions.size(); iIdx++) {
			
			//Check whether the action is meaningful
			if (testCase.preconditions.get(iIdx).equals(null)
					|| testCase.preconditions.get(iIdx).equals("")
					|| testCase.preconditions.get(iIdx).equals(" ")
					|| testCase.preconditions.get(iIdx).equals("null")) {
				continue;
			}

			//Get actions line by line
			String[] testActions = testCase.preconditions.get(iIdx).split("\n");
			
			for (int actions = 0; actions < testActions.length; actions++) {
				//Check whether the action is meaningful
				if (testActions[actions].equals(" ")
						|| testActions[actions].equals("")
						|| testActions[actions].equals(null)
						|| testActions[actions].equals("null")) {
					continue;
				}
				//Apply format to the action
				preconditions += "<p>" + testActions[actions] + "</p>";
			}
		}
		//Replace precondition marker with all colected actions
		reportPreconditions += report.replace(PRECONDITIONS, preconditions);

		return reportPreconditions;
	}

	//Get current date and format it
	private String now(String format) {
		Calendar cal = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(cal.getTime());
	}

	//Return formated current date 
	private String now() {
		return now("yyyy_MM_dd_HH_mm_ss");
	}

	//Generate report unique name 
	public String generateReportName(String projectName, String testCaseID) {
		String reportName = null;

		//Project Name + Test Case ID + Current Date and Time + .htm
		reportName = projectName + "_" + testCaseID + "_" + now() + ".htm";

		return reportName;
	}

	//Format test result by applying appropriate color: FAILURE - RED ; PASS - GREEN
	private String formatTestResult(boolean result) {
		String tcResult = null;

		if (result) {
			tcResult = "<font color=\"green\" style=\"font-weight:bold\">"
					+ "PASS" + "</font>";
		} else {
			tcResult = "<font color=\"red\" style=\"font-weight:bold\">"
					+ "FAILURE" + "</font>";
		}

		return tcResult;
	}

	//Format test action 
	private String formatTestActions(TestStep testStep) {
		String reportActions = "";

		//Iterate through all collected actions and pass if the action make no sense
		for (int iIdx = 0; iIdx < testStep.actions.size(); iIdx++) {
			if (testStep.actions.get(iIdx) == null) {
				continue;
			}

			//Split the actions line by line
			String[] testActions = testStep.actions.get(iIdx).split("\n");
			
			//Iterate through all collected meaningfull methods
			for (int actions = 0; actions < testActions.length; actions++) {
				
				//Not sure that is needed
				if (testActions[actions].equals(" ")
						|| testActions[actions].equals("")
						|| testActions[actions].equals(null)) {
					continue;
				}
				
				//Replace step action marker with appropriate action
				reportActions += color(STEP_ACTIONS_HTML.replace(STEP_ACTIONS,
						testActions[actions]), testStep.isResultOK());
			}
		}
		
		//Write message in the report if there is no action
		if (reportActions == null) {
			reportActions = "No Test Step Action!";
		}

		return reportActions;
	}

	//Format Test Step
	private String formatTestStep(TestStep testStep) {
		String reportStep = null;

		reportStep = TEST_STEP_HTML.replace(STEP_ACTIONS,
				formatTestActions(testStep));
		reportStep = reportStep.replace(TS_RESULT, formatTestResult(testStep
				.isResultOK()));
		reportStep = reportStep
				.replace(TEST_STEP, testStep.getExpectedResult());

		return reportStep;
	}

	//Concatenate all test steps in the test case report
	private String concatenateAllSteps(TestCase testCase) {
		String reportSteps = "";

		for (int iIdx = 0; iIdx < testCase.getStepsCount(); iIdx++) {
			if (testCase.testSteps.get(iIdx) == null) {
				continue;
			}
			reportSteps += formatTestStep(testCase.testSteps.get(iIdx));
		}

		reportSteps = reportSteps.replaceAll("null", "");

		return reportSteps;
	}

	//Generate test report
	public String generateReport(TestCase testCase, String project) {
		String report = "";
		try {
			report = FileOperator.getContents(System.getProperty("user.dir")
					+ "\\core\\Report.htm");
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		String reportName = null;

		report = formatHeader(report, project, testCase.getTestCaseID(),
				testCase.getTestCaseDescription(), testCase.getPerformedBy(),
				testCase.getCreatedBy(), testCase.getCoveredRequirement(),
				testCase.getCoveredDefect(), testCase.getTestCaseComment());

		report = formatPreconditions(report, testCase);

		report = report.replace(TEST_STEPS, concatenateAllSteps(testCase));

		report = formatFooter(report, formatTestResult(testCase.isResult()),
				testCase.getBriefDescription());

		// Generate report
		try {
			reportName = reportPath(project) + "\\"
					+ generateReportName(project, testCase.getTestCaseID());
			FileOperator.setContents(reportName, report);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return reportName;
	}

	//Get report file path
	private String reportPath(String project) {
		String path = System.getProperty("user.dir");

		File dir = new File(path);
		if (!(new File(dir.getParent() + "\\" + project + "_logs")).exists()) {
			(new File(dir.getParent() + "\\" + project + "_logs")).mkdir();
		}
		path = dir.getParent() + "\\" + project + "_logs";

		return path;
	}

	//Apply color to the HTML text 
	private String color(String content, boolean isOK) {
		String resultContnt = null;

		if (isOK) {
			resultContnt = "<font color=\"green\" >" + content + "</font>";
		} else {
			resultContnt = "<font color=\"red\" >" + content + "</font>";
		}

		return resultContnt;
	}
}

